#include "PostOffice.h"
#include "World.h"

std::map<std::string, std::list<Entity*> > PostOffice::groups__;

PostOffice::PostOffice()
{
}

PostOffice::~PostOffice()
{
}

void PostOffice::RegisterGroup(Entity* entity, const std::string& group)
{
	if (group != "")
		groups__[group].push_back(entity);
}

// TODO: test this
void PostOffice::UnregisterAllGroups(Entity* entity)
{
	std::map<std::string, std::list<Entity*> >::iterator it = groups__.begin();
	UnregisterGroup(entity, it->first);
}

void PostOffice::UnregisterGroup(Entity* entity, const std::string& group)
{
	if (group == "")
		return;
	
	std::map<std::string, std::list<Entity*> >::iterator it = groups__.find(group);

	if (it != groups__.end())
	{
		std::list<Entity*>::iterator it2 = it->second.begin();
		while (it2 != it->second.end())
		{
			if (*it2 == entity)
			{
				it->second.erase(it2);
				return;
			}
			it2++;
		}
	}
}

bool PostOffice::DispatchMessage(Entity * emitter,const std::string& group, const std::string& message)
{
	int counter = 0;
	std::map<std::string, std::list<Entity*> >::iterator it = groups__.find(group);


	if (it == groups__.end())
		return false;
	
	std::list<Entity*>::iterator it2 = it->second.begin();
	while (it2 != it->second.end())
	{
		(*it2)->mailbox__.push_back(Message(emitter,message));
		counter++;

		it2++;
	}

	return counter > 0;
}

bool PostOffice::DispatchMessage(Entity * emitter, const std::string& group, const std::string& message, const std::string& extra, const irr::core::vector3df about)
{
	int counter = 0;
	std::map<std::string, std::list<Entity*> >::iterator it = groups__.find(group);


	if (it == groups__.end())
		return false;
	
	std::list<Entity*>::iterator it2 = it->second.begin();
	while (it2 != it->second.end())
	{
		(*it2)->mailbox__.push_back(Message(emitter,message,extra,about));
		counter++;

		it2++;
	}

	return counter > 0;
}

bool PostOffice::DispatchMessage(Entity * emitter, Entity* receiver, const std::string& message)
{
	Map* m = World::getMap();
	if (m == 0)
		return false;
	
	std::map<ISceneNode*, Entity*>::iterator it = m->entities__.begin();
	while (it != m->entities__.end())
	{
		if (it->second == receiver)
		{
			it->second->mailbox__.push_back(Message(emitter,message));
			return true;
		}
		it++;
	}
	return false;
}

bool PostOffice::DispatchMessage(Entity * emitter, Entity* receiver, const std::string& message,const std::string& extra)
{
	Map* m = World::getMap();
	if (m == 0)
		return false;
	
	std::map<ISceneNode*, Entity*>::iterator it = m->entities__.begin();
	while (it != m->entities__.end())
	{
		if (it->second == receiver)
		{
			it->second->mailbox__.push_back(Message(emitter,message,extra));
			return true;
		}
		it++;
	}
	return false;
}

bool PostOffice::DispatchMessage(Entity * emitter, Entity* receiver, const std::string& message,const std::string& extra, const irr::core::vector3df about)
{
	Map* m = World::getMap();
	if (m == 0)
		return false;
	
	std::map<ISceneNode*, Entity*>::iterator it = m->entities__.begin();
	while (it != m->entities__.end())
	{
		if (it->second == receiver)
		{
			it->second->mailbox__.push_back(Message(emitter,message,extra,about));
			return true;
		}
		it++;
	}
	return false;
}

